package com.gosophia.dataDictionary.ws.impl;

import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.WebServiceException;

import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.gosophia.commons.OrderCondition;
import com.gosophia.commons.Page;
import com.gosophia.commons.exception.BusinessException;
import com.gosophia.commons.exception.ConcurrencyException;
import com.gosophia.commons.exception.ParameterException;
import com.gosophia.commons.exception.TechnicalException;
import com.gosophia.dataDictionary.dto.DataEntryDTO;
import com.gosophia.dataDictionary.dto.DataValueDTO;
import com.gosophia.dataDictionary.entity.DataEntry;
import com.gosophia.dataDictionary.entity.DataValue;
import com.gosophia.dataDictionary.service.DataDictionaryService;
import com.gosophia.dataDictionary.ws.DataDictionaryWebService;

/**
 * 机 能：本类是DataDictionaryWebService类的实现类
 * 
 * @author mayue
 * @since 2010-11-22 Copyright (c) 2010 Gosophia corporation All Rights
 *        Reserved.
 */
@Transactional
@Service("dataDictionaryWebServiceImpl")
public class DataDictionaryWebServiceImpl implements DataDictionaryWebService {

    @Autowired
    private DataDictionaryService dataDictionaryService;

    @Autowired
    private Mapper dozer;

    /**
     * 添加数据值
     * 
     * @param dataValueDTO
     *            不能为null，dataValueDTO.dataValueId必须为null
     * @throws BusinessException
     * @throws WebServiceException
     *             ,当同一词条下的dataValueDTO.value重复或dataValueDTO.key重复时
     */
    @Override
    public Long addDataValue(DataValueDTO dataValueDTO, Long toId)
            throws BusinessException {
        Assert.notNull(dataValueDTO, "dataValueDTO不能为null");
        Assert.isTrue(dataValueDTO.getDataValueId() == null,
                "dataValueId必须为null");
        DataValue dataValue = dozer.map(dataValueDTO, DataValue.class);
        DataEntry entry = dataDictionaryService.findDataEntryById(dataValueDTO
                .getEntryId());
        dataValue.setDataEntry(entry);
        dataDictionaryService.addDataValue(dataValue, toId);
        DataValue dv = dataDictionaryService.findDataValueByEntryIdAndKey(entry
                .getEntryId(), dataValue.getKey());
        if (dv != null) {
            return dv.getDataValueId();
        } else
            return null;
    }

    /**
     * 删除数据值
     * 
     * @param dataValueId
     *            不能为null;
     * @param version
     *            不能为null
     * @throws BusinessException
     * @throws ConcurrencyException
     * @throws WebServiceException
     *             ，当数据值被引用时
     * @throws BusinessException
     * @throws ConcurrencyException
     */
    @Override
    public void removeDataValue(DataValueDTO dataValueDto)
            throws BusinessException {
        Assert.notNull(dataValueDto, "dataValue不能为null");
        Assert.notNull(dataValueDto.getDataValueId(), "dataValueId不能为null");
        Assert.notNull(dataValueDto.getVersion(), "version不能为null");
        dataDictionaryService.removeDataValue(dataValueDto.getDataValueId(),
                dataValueDto.getVersion());

    }

    /**
     * 修改数据值
     * 
     * @param dataValue
     *            ，dataValueDTO.dataValueId不能为null
     * @throws WebServiceException
     *             ,当同一词条下的dataValueDTO.value重复或dataValueDTO.key重复时
     * @throws BusinessException
     */
    @Override
    public void updateDataValue(DataValueDTO dataValueDTO)
            throws BusinessException {
        Assert.notNull(dataValueDTO, "dataValueDTO不能为null");
        Assert.notNull(dataValueDTO.getDataValueId(), "dataValueId不能为null");
        DataValue dataValue = dozer.map(dataValueDTO, DataValue.class);
        dataValue.setDataEntry(dataDictionaryService
                .findDataEntryById(dataValueDTO.getEntryId()));
        dataDictionaryService.updateDataValue(dataValue);
    }

    /**
     * 根据词条id和数据值的key查询数据值
     * 
     * @param entryId
     *            不能为null
     * @param key
     *            不能为null
     * @return 返回根据词条id和数据值的key查询数据值，如果不存在返回null
     * @throws WebServiceException
     */
    @Override
    public DataValueDTO findDataValueByEntryIdAndKey(Long entryId, String key)
            throws ParameterException, ConcurrencyException, TechnicalException {
        Assert.notNull(entryId, "entryId不能为null");
        Assert.notNull(key, "key不能为null");
        DataValue dataValue = dataDictionaryService
                .findDataValueByEntryIdAndKey(entryId, key);
        DataValueDTO dataValueDTO = dozer.map(dataValue, DataValueDTO.class);
        dataValueDTO.setEntryId(dataValue.getDataEntry().getEntryId());
        return dataValueDTO;
    }

    /**
     * 根据词条Id返回启用的数据值集合
     * 
     * @param entryId
     *            不能为null
     * @return 返回根据词条Id查找的启用数据值集合（按排序号排序）
     * @throws WebServiceException
     */
    @Override
    public List<DataValueDTO> findEnabledDataValueByEntryId(Long entryId)
            throws ParameterException, ConcurrencyException, TechnicalException {
        Assert.notNull(entryId, "entryId不能为null");
        List<DataValue> dataValues = dataDictionaryService
                .findEnabledDataValueByEntryId(entryId);
        if (dataValues == null || dataValues.size() == 0) {
            return null;
        }
        List<DataValueDTO> dataValueDTOs = new ArrayList<DataValueDTO>();
        for (DataValue d : dataValues) {
            DataValueDTO dataValueDTO = dozer.map(d, DataValueDTO.class);
            dataValueDTO.setEntryId(d.getDataEntry().getEntryId());
            dataValueDTOs.add(dataValueDTO);
        }
        return dataValueDTOs;
    }

    /**
     * 查找词条，如果没有过滤条件，返回所有词条的分页信息;有过滤条件，返回满足条件的词条分页信息
     * 
     * @param pageNo
     *            页码 页码必须大于0
     * @param pageSize
     *            每页的最大记录条数 必须大于0
     * @param propertyFilters
     *            过滤条件，可以为null;每个过滤条件都是PropertyFilter类的一个对象 每个过滤条件可以通过以下方法来创建
     *            PropertyFilter propertyFilter = new
     *            PropertyFilter(propertyName, operator, propertyValue);
     *            propertyName 实体属性名称（字符串类型） 该接口可用属性名称有：entryName，entryNote
     *            operator 操作类型（枚举类型） 可通过OperatorType来获取 propertyValue
     *            实体属性对应的值（字符串类型） 可根据需要设置实体属性对应的值
     * @param orderConditions
     *            排序条件，可以为null;每个排序条件都是 OrderCondition类的一个对象 每个排序条件可以通过以下方法来创建
     *            OrderCondition or = new OrderCondition(propertyName,
     *            ascending); propertyName 实体属性名称（字符串类型）
     *            该接口可用属性名称有：entryName，entryNote ascending
     *            排序顺序（boolean类型），为true时代表升序，否则为降序
     * @return 返回满足条件的词条
     * @throws WebServiceException
     */
    @Override
    public Page<DataEntryDTO> findEntriesByPage(int pageNo, int pageSize,
            String searchCon, List<OrderCondition> orderConditions)
            throws ParameterException, ConcurrencyException, TechnicalException {
        Assert.isTrue(pageNo > 0, "pageNo必须大于0");
        Assert.isTrue(pageSize > 0, "pageSize必须大于0");

        Page<DataEntry> entryPage = dataDictionaryService
                .findDataEntriesByPage(pageNo, pageSize, searchCon,
                        orderConditions);
        List<DataEntry> entrys = entryPage.getResult();
        if (entrys == null) {
            return new Page<DataEntryDTO>();
        }
        List<DataEntryDTO> entryDTOs = new ArrayList<DataEntryDTO>();
        for (DataEntry e : entrys) {
            // List<DataValue> dvs = e.getDataValues();
            DataEntryDTO entryDTO = dozer.map(e, DataEntryDTO.class);
            entryDTO.setDataValues(null);
            // if (dvs != null && dvs.size() != 0) {
            // List<DataValueDTO> dvDtos = new ArrayList<DataValueDTO>();
            // for (DataValue dataValue : dvs) {
            // DataValueDTO dvdto = dozer.map(dataValue,
            // DataValueDTO.class);
            // dvdto.setEntryId(dataValue.getDataEntry().getEntryId());
            // dvDtos.add(dvdto);
            // }
            // entryDTO.setDataValues(dvDtos);
            // }
            entryDTOs.add(entryDTO);
        }
        Page<DataEntryDTO> page = new Page<DataEntryDTO>();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        page.setResult(entryDTOs);
        page.setTotalCount(entryPage.getTotalCount());
        return page;
    }

    /**
     * 根据词条名称和键值查找数据值
     * 
     * @param entryName
     *            不能为null
     * @param key
     *            不能为null
     * @return 符合条件的数据值，没有数据返回null
     */
    @Override
    public DataValueDTO findDataValueByEntryNameAndKey(String entryName,
            String key) {
        DataValueDTO dataValueDTO = null;
        Assert.notNull(entryName, "entryName不能为null");
        Assert.notNull(key, "key不能为null");
        DataValue dataValue = dataDictionaryService
                .findDataValueByEntryNameAndKey(entryName, key);
        dataValueDTO = dozer.map(dataValue, DataValueDTO.class);
        dataValueDTO.setEntryId(dataValue.getDataEntry().getEntryId());
        return dataValueDTO;
    }

    /**
     * 根据词条名称查找启用的数据值
     * 
     * @param entryName
     *            不能为null
     * @return 符合条件的数据值列表，没有数据返回null
     */
    @Override
    public List<DataValueDTO> findEnabledDataValueByEntryName(String entryName)
            throws ParameterException, ConcurrencyException, TechnicalException {
        List<DataValueDTO> dataValueDTOs = null;
        Assert.isTrue(entryName != null, "entryName不能为null");
        List<DataValue> dataValues = dataDictionaryService
                .findEnabledDataValueByEntryName(entryName);
        dataValueDTOs = new ArrayList<DataValueDTO>();
        for (DataValue d : dataValues) {
            DataValueDTO dataValueDTO = dozer.map(d, DataValueDTO.class);
            dataValueDTO.setEntryId(d.getDataEntry().getEntryId());
            dataValueDTOs.add(dataValueDTO);
        }
        return dataValueDTOs;
    }

    /**
     * 通过词条id查找词条
     */
    @Override
    public DataEntryDTO findDataEntryByDataEntryId(Long dataEntryId)
            throws ParameterException, ConcurrencyException, TechnicalException {
        Assert.notNull(dataEntryId, "dataEntryId不能为null");
        DataEntry dataEntry = dataDictionaryService
                .findDataEntryById(dataEntryId);
        
        DataEntryDTO dataEntryDTO = dozer.map(dataEntry, DataEntryDTO.class);
        List<DataValue> dataValues = dataEntry.getDataValues();
        if (dataValues != null && dataValues.size() != 0) {
            List<DataValueDTO> dataValueDTOs = new ArrayList<DataValueDTO>();
            for (DataValue d : dataValues) {
                DataValueDTO dataValueDTO = dozer.map(d, DataValueDTO.class);
                dataValueDTO.setEntryId(d.getDataEntry().getEntryId());
                dataValueDTOs.add(dataValueDTO);
            }
            dataEntryDTO.setDataValues(dataValueDTOs);
        }
        return dataEntryDTO;
    }

    /**
     * 移动数据值
     */
    @Override
    public void moveDataValue(Long fromId, Long toId, Long entryId) {
        Assert.notNull(fromId, "fromId不能为null");
        Assert.notNull(entryId, "entryId不能为null");
        dataDictionaryService.moveDataValue(fromId, toId, entryId);

    }

    /**
     * 根据数据值id查找数据值
     */
    @Override
    public DataValueDTO findDataValueByDataValueId(Long dataValueId) {
        Assert.notNull(dataValueId, "dataValueId不能为null");
        DataValue dataValue = dataDictionaryService
                .findDataValueByDataValueId(dataValueId);
        DataValueDTO dataValueDTO = dozer.map(dataValue, DataValueDTO.class);
        dataValueDTO.setEntryId(dataValue.getDataEntry().getEntryId());
        return dataValueDTO;
    }

}
